export interface ViewportOffsetResult {
	left: number;
	top: number;
	right: number;
	bottom: number;
	rightIncludeBody: number;
	bottomIncludeBody: number;
}

export function getBoundingClientRect(element: Element): DOMRect | number {
	if (!element || !element.getBoundingClientRect) return 0;

	return element.getBoundingClientRect();
}

/**
 * Get the left and top offset of the current element
 * left: the distance between the leftmost element and the left side of the document
 * top: the distance from the top of the element to the top of the document
 * right: the distance from the far right of the element to the right of the document
 * bottom: the distance from the bottom of the element to the bottom of the document
 * rightIncludeBody: the distance between the leftmost element and the right side of the document
 * bottomIncludeBody: the distance from the bottom of the element to the bottom of the document
 *
 * @description:
 */
export function getViewportOffset(element: Element): ViewportOffsetResult {
	const doc = document.documentElement;

	const docScrollLeft = doc.scrollLeft;
	const docScrollTop = doc.scrollTop;
	const docClientLeft = doc.clientLeft;
	const docClientTop = doc.clientTop;

	const pageXOffset = window.pageXOffset;
	const pageYOffset = window.pageYOffset;

	const box = getBoundingClientRect(element);

	const { left: retLeft, top: rectTop, width: rectWidth, height: rectHeight } = box as DOMRect;

	const scrollLeft = (pageXOffset || docScrollLeft) - (docClientLeft || 0);
	const scrollTop = (pageYOffset || docScrollTop) - (docClientTop || 0);
	const offsetLeft = retLeft + pageXOffset;
	const offsetTop = rectTop + pageYOffset;

	const left = offsetLeft - scrollLeft;
	const top = offsetTop - scrollTop;

	const clientWidth = window.document.documentElement.clientWidth;
	const clientHeight = window.document.documentElement.clientHeight;
	return {
		left,
		top,
		right: clientWidth - rectWidth - left,
		bottom: clientHeight - rectHeight - top,
		rightIncludeBody: clientWidth - left,
		bottomIncludeBody: clientHeight - top
	};
}
